#include<stdio.h>
#include<unistd.h>
#include<netdb.h>
#include<string.h>
#include<stdlib.h>
#include"ohos_init.h"
#include"cmsis_os2.h"
#include"lwip/netifapi.h"
#include"lwip/api_shell.h"
#include "lwip/sockets.h"
#include "wifi_device.h"
#include "wifi_hotspot.h"
#include "wifi_error_code.h"
#include "lwip/netifapi.h"
#include "kv_store.h"
#include "iot_i2c.h"
#include "iot_i2c_ex.h"
#include "iot_gpio.h"
#include "iot_gpio_ex.h"
#include <iot_spi.h>

#include "iot_gpio.h"
#include "iot_gpio_ex.h"
#include <hi_adc.h>
#include <iot_adc.h>

#include "cmsis_os2.h"
#include "ohos_init.h"

#include <stdio.h>
#include <string.h>
#include <unistd.h>

#include "cmsis_os2.h"
#include "iot_errno.h"
#include "iot_uart.h"
#include "ohos_init.h"


#define I2C_TASK_STACK_SIZE 1024 * 8
#define I2C_TASK_PRIO 25

//I2C引脚
#define I2C_SDA_GPIO_IDX 13
#define I2C_SCL_GPIO_IDX 14
#define GY39_ADDR 0X5B
//I2C序号
#define WIFI_IOT_I2C_IDX_0 0
#define I2C_WRITE_FLAG 0

// 读取指定寄存器的数据
unsigned char read_register(unsigned short address) {
    unsigned char data[1]={0};
    if (IoTI2cRead(WIFI_IOT_I2C_IDX_0, (GY39_ADDR << 1) |address, &data, 1) != IOT_SUCCESS) {
        // 处理读取失败的情况，这里可以根据实际需求进行处理
        printf("I2C 5b read faild\n");
    }
    if (IoTI2cRead(WIFI_IOT_I2C_IDX_0, (0xB6 << 1) |address, &data, 1) != IOT_SUCCESS) {
        // 处理读取失败的情况，这里可以根据实际需求进行处理
        printf("I2C b6 read faild\n");
    }
    return data;
}

// 读取光照强度
unsigned int read_lux() {
    unsigned char lux_fh, lux_fl, lux_ah, lux_al;
    lux_fh = read_register(0x00);
    lux_fl = read_register(0x01);
    lux_ah = read_register(0x02);
    lux_al = read_register(0x03);
    return (lux_fh << 24) | (lux_fl << 16) | (lux_ah << 8) | lux_al;
}

// 读取温度
float read_temperature() {
    unsigned char t_h, t_l;
    t_h = read_register(0x04);
    t_l = read_register(0x05);
    unsigned int temperature = (t_h << 8) | t_l;
    return temperature / 100.0;  // 将结果转换为浮点数再返回
}

// 读取气压
unsigned int read_pressure() {
    unsigned char p_fh, p_fl, p_ah, p_al;
    p_fh = read_register(0x06);
    p_fl = read_register(0x07);
    p_ah = read_register(0x08);
    p_al = read_register(0x09);
    return (p_fh << 24) | (p_fl << 16) | (p_ah << 8) | p_al;
}

// 读取湿度
float read_humidity() {
    unsigned char h_h, h_l;
    h_h = read_register(0x0a);
    h_l = read_register(0x0b);
    unsigned int h = (h_h << 8) | h_l;
    return h / 100.0;
}

// 读取海拔
unsigned int read_altitude() {
    unsigned char alt_h, alt_l;
    alt_h = read_register(0x0c);
    alt_l = read_register(0x0d);
    return (alt_h << 8) | alt_l;
}

static float GetVoltage(void)
{
    unsigned int ret;
    unsigned short data;
    

    ret = IoTAdcRead(HI_ADC_CHANNEL_3, &data,IOT_ADC_EQU_MODEL_8,HI_ADC_CUR_BAIS_DEFAULT,0);
    if (ret != IOT_SUCCESS) {
        printf("ADC Read Fail\n");
    }

    return (float)data;
}


static void I2CTask(void)
{
    uint8_t data[14] = {0};
    uint16_t data_16[2]={0};
    uint32_t Lux,Alt,Hum,P,Temp;
    float soildHumi;

    //初始化io
    IoTGpioInit(I2C_SDA_GPIO_IDX);
    // GPIO_13复用为I2C0_SDA
    IoTGpioSetFunc(I2C_SDA_GPIO_IDX, IOT_GPIO_FUNC_GPIO_13_I2C0_SDA); 
    IoTGpioInit(I2C_SCL_GPIO_IDX);
    // GPIO_14复用为I2C0_SCL
    IoTGpioSetFunc(I2C_SCL_GPIO_IDX, IOT_GPIO_FUNC_GPIO_14_I2C0_SCL); 
    //初始化I2C并设置波特率
    IoTI2cInit(WIFI_IOT_I2C_IDX_0, 4000);

    printf("I2C Test Start\n");

    while (1)
    {
        if (IoTI2cRead(WIFI_IOT_I2C_IDX_0, (GY39_ADDR << 1) |0x00, &data, 14) != IOT_SUCCESS) {
        printf("I2C 04 read faild\n");
    }
        Temp=(data[4]<<8)|data[5];
        data_16[0]=(((uint16_t)data[6])<<8)|data[7];
        data_16[1]=(((uint16_t)data[8])<<8)|data[9];
        P=(((uint32_t)data_16[0])<<16)|data_16[1];
        Hum=(data[10]<<8)|data[11];
        Alt=(data[12]<<8)|data[13];

        data_16[0]=(((uint16_t)data[0])<<8)|data[1];
        data_16[1]=(((uint16_t)data[2])<<8)|data[3];
        Lux=(((uint32_t)data_16[0])<<16)|data_16[1];
        soildHumi=GetVoltage();

        printf("Temp: %.2f  DegC \n ",(float)Temp/100);
		printf("  P: %.2f  Pa \n",(float)P/100);
		printf("  Hum: %.2f  \n ",(float)Hum/100);
		printf("  Alt: %.2f  m\n ",(float)Alt);
		printf(" Lux: %.2f  lux\n ",(float)Lux/100); 
        printf("SoildHumi : %.2f  \n",soildHumi);
        sleep(2);  
    }
    
    

}

static void I2CExampleEntry(void)
{
    osThreadAttr_t attr;

    attr.name = "I2CTask";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = I2C_TASK_STACK_SIZE;
    attr.priority = I2C_TASK_PRIO;

    if (osThreadNew((osThreadFunc_t)I2CTask, NULL, &attr) == NULL)
    {
        printf("Falied to create I2CTask!\n");
    }
}

APP_FEATURE_INIT(I2CExampleEntry);